home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 41.zip / BS1 part 41 / Compute`s Amiga resource 1.adf / Source / X-Ray / X-Ray.c
C/C++ Source or Header  |  1989-02-07  |  17KB  |  772 lines

  1. /*
  2.    X-Ray
  3.    By Randy Thompson
  4.    Copyright 1989 COMPUTE! Publications, Inc.
  5.    All Rights Reserved
  6.    Last modified 01/31/89
  7.  
  8.    Compile with Lattice C 5.0
  9.    lc -L -O X-Ray
  10. */
  11.  
  12. /*
  13.    Startup code for NOT opening a window when run from the Workbench.
  14. */
  15. #include <stdio.h>
  16. #include <fcntl.h>
  17. #include <ios1.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <workbench/startup.h>
  21. #include <libraries/dos.h>
  22. #include <libraries/dosextens.h>
  23. #include <proto/dos.h>
  24. #include <proto/exec.h>
  25.  
  26. #define MAXARG 32              /* maximum command line arguments */
  27. #define QUOTE  '"'
  28. #define isspace(c)      ((c == ' ')||(c == '\t') || (c == '\n'))
  29.  
  30. extern struct UFB _ufbs[];
  31. int argc;                       /* arg count */
  32. char **targv, *argv[MAXARG];     /* arg pointers */
  33.  
  34. #define MAXWINDOW 40
  35. extern struct WBStartup *WBenchMsg;
  36.  
  37. void _main(line)
  38. register char *line;
  39. {
  40. register char **pargv;
  41.  
  42. while (argc < MAXARG)
  43.         {
  44.         while (isspace(*line))  line++;
  45.         if (*line == '\0')      break;
  46.         pargv = &argv[argc++];
  47.         if (*line == QUOTE)
  48.                 {
  49.                 *pargv = ++line;  /* ptr inside quoted string */
  50.                 while ((*line != '\0') && (*line != QUOTE)) line++;
  51.                 if (*line == '\0')  _exit(1);
  52.                 else                *line++ = '\0';  /* terminate arg */
  53.                 }
  54.         else            /* non-quoted arg */
  55.                 {       
  56.                 *pargv = line;
  57.                 while ((*line != '\0') && (!isspace(*line))) line++;
  58.                 if (*line == '\0')  break;
  59.                 else                *line++ = '\0';  /* terminate arg */
  60.                 }
  61.         }  /* while */
  62. targv = (argc == 0) ? (char **)WBenchMsg : (char **)&argv[0];
  63.  
  64. main(argc,targv);              /* call main function */
  65. _exit(0);
  66. }
  67.  
  68.  
  69. /*
  70.    Beginning of main program.
  71. */
  72. #include <exec/types.h>
  73. #include <exec/memory.h>
  74. #include <devices/timer.h>
  75. #include <graphics/gfxmacros.h>
  76. #include <intuition/intuitionbase.h>
  77.  
  78.  
  79. #define TITLE     "X-Ray"
  80. #define CREDIT    "by Randy Thompson"
  81. #define COPYRIGHT "X-Ray \xA9 1989 COMPUTE! Publications, Inc. All Rights Reserved."
  82.  
  83. #define VERT      0
  84. #define HORIZ     1
  85. #define NEXT      2
  86. #define PREV      3
  87. #define ENTER     4
  88.  
  89. #define MINWIDTH  160
  90. #define MINHEIGHT 32
  91. #define DEFWIDTH  200
  92. #define DEFHEIGHT 100
  93.  
  94. #define LSHFTCLCK 0x8001
  95. #define RSHFTCLCK 0x8002
  96.  
  97. #define ON        TRUE
  98. #define OFF       FALSE
  99. #define DEFTICK   200000;
  100.  
  101. #define FVPORT    &(FScreen->ViewPort)
  102. #define BBMAP     &(BScreen->BitMap)
  103. #define WRPORT    Window->RPort
  104. #define TIMREQ    timerequest
  105.  
  106.  
  107. void             InitProgram();
  108. void             OpenXRWindow();
  109. void             AdjustProps();
  110. BOOL             AdjustLimits();
  111. void             DoGadget();
  112. void             IncScreen();
  113. void             DecScreen();
  114. void             SetScreen();
  115. struct TIMREQ   *OpenTimer();
  116. void             CloseTimer();
  117. void             QueueTimer();
  118. void             Follow();
  119. void             SwapIn();
  120. void             SwapOut();
  121. void             Quit();
  122.  
  123.  
  124. struct IntuitionBase *IntuitionBase = NULL;
  125. struct LayersBase    *LayersBase = NULL;
  126. struct GfxBase       *GfxBase = NULL;
  127.  
  128. struct MsgPort       *TimerPort = NULL;
  129. struct TIMREQ        *TimeRequest = NULL;
  130.  
  131. struct Screen        *FScreen = NULL;
  132. struct Screen        *BScreen = NULL;
  133.  
  134. SHORT  FWidth, FHeight;
  135. SHORT  BWidth, BHeight;
  136. SHORT  WWidth, WHeight;
  137. ULONG  Dx, Dy;
  138.  
  139. ULONG  Micros;
  140. ULONG  Secs;
  141. BOOL   Timer;
  142.  
  143. USHORT Colors[255], NumReg;
  144.  
  145.  
  146. USHORT chip PrevImageData[] = {
  147.    /* plane 1 */
  148.    0x03FF,0xFFF0,
  149.    0x03FF,0xFFF0,
  150.    0x03C0,0x00F0,
  151.    0x03C0,0x00F0,
  152.    0x03C0,0x00F0,
  153.    0x03F0,0x03F0,
  154.    0x03FC,0x0FF0,
  155.    0x03FF,0x3FF0,
  156.    0x03FF,0xFFF0,
  157.    0x03FF,0xFFF0,
  158.    /* plane 2 */
  159.    0x0000,0x0000,
  160.    0x0000,0x0000,
  161.    0x003F,0xFF00,
  162.    0x003F,0xFF00,
  163.    0x003F,0xFF00,
  164.    0x000F,0xFC00,
  165.    0x0003,0xF000,
  166.    0x0000,0xC000,
  167.    0x0000,0x0000,
  168.    0x0000,0x0000
  169. };
  170. struct Image PrevImage = {
  171.    -4,0,
  172.    28,10,2,
  173.    PrevImageData,
  174.    3,0,
  175.    NULL
  176. };
  177. struct Gadget PrevGadget = {
  178.    NULL,
  179.    0,0,
  180.    24,10,
  181.    GADGHCOMP | GADGIMAGE | GRELRIGHT,
  182.    GADGIMMEDIATE | RELVERIFY,
  183.    BOOLGADGET | GZZGADGET,
  184.    (APTR)&PrevImage,
  185.    NULL,
  186.    NULL,
  187.    0,
  188.    NULL,
  189.    PREV,
  190.    NULL
  191. };
  192.  
  193. USHORT chip NextImageData[] = {
  194.    /* plane 1 */
  195.    0x03FF,0xFFF0,
  196.    0x03FF,0xFFF0,
  197.    0x03FF,0x3FF0,
  198.    0x03FC,0x0FF0,
  199.    0x03F0,0x03F0,
  200.    0x03C0,0x00F0,
  201.    0x03C0,0x00F0,
  202.    0x03C0,0x00F0,
  203.    0x03FF,0xFFF0,
  204.    0x03FF,0xFFF0,
  205.    /* plane 2 */
  206.    0x0000,0x0000,
  207.    0x0000,0x0000,
  208.    0x0000,0xC000,
  209.    0x0003,0xF000,
  210.    0x000F,0xFC00,
  211.    0x003F,0xFF00,
  212.    0x003F,0xFF00,
  213.    0x003F,0xFF00,
  214.    0x0000,0x0000,
  215.    0x0000,0x0000
  216. };
  217. struct Image NextImage = {
  218.    -4,0,
  219.    28,10,2,
  220.    NextImageData,
  221.    3,0,
  222.    NULL
  223. };
  224. struct Gadget NextGadget = {
  225.    NULL,
  226.    0,0,
  227.    24,10,
  228.    GADGHCOMP | GADGIMAGE | GRELRIGHT,
  229.    GADGIMMEDIATE | RELVERIFY,
  230.    BOOLGADGET | GZZGADGET,
  231.    (APTR)&NextImage,
  232.    NULL,
  233.    NULL,
  234.    0,
  235.    NULL,
  236.    NEXT,
  237.    NULL
  238. };
  239.  
  240. USHORT chip EnterImageData[] = {
  241.    /* plane 1 */
  242.    0xF3FF,0xFFF0,
  243.    0xF3C3,0xF0F0,
  244.    0xF3F0,0xC3F0,
  245.    0xF3FC,0x0FF0,
  246.    0xF3FE,0x1FF0,
  247.    0xF3FC,0x0FF0,
  248.    0xF3F0,0xC3F0,
  249.    0xF3C3,0xF0F0,
  250.    0xF3FF,0xFFF0,
  251.    0xF3FF,0xFFF0,
  252.    /* plane 2 */
  253.    0x0000,0x0000,
  254.    0x003C,0x0F00,
  255.    0x000F,0x3C00,
  256.    0x0003,0xF000,
  257.    0x0001,0xE000,
  258.    0x0003,0xF000,
  259.    0x000F,0x3C00,
  260.    0x003C,0x0F00,
  261.    0x0000,0x0000,
  262.    0x0000,0x0000
  263. };
  264. struct Image EnterImage = {
  265.    -4,0,
  266.    28,10,2,
  267.    EnterImageData,
  268.    3,0,
  269.    NULL
  270. };
  271. struct Gadget EnterGadget = {
  272.    NULL,
  273.    0,0,
  274.    24,10,
  275.    GADGHCOMP | GADGIMAGE | GRELRIGHT,
  276.    GADGIMMEDIATE | RELVERIFY,
  277.    BOOLGADGET | GZZGADGET,
  278.    (APTR)&EnterImage,
  279.    NULL,
  280.    NULL,
  281.    0,
  282.    NULL,
  283.    ENTER,
  284.    NULL
  285. };
  286.  
  287. struct Image HorizImage;
  288. struct PropInfo HorizPropInfo = {
  289.    AUTOKNOB | FREEHORIZ,
  290.    0,0,
  291.    0,0,
  292.    0,0,
  293.    0,0,
  294.    0,0
  295. };
  296. struct Gadget HorizGadget = {
  297.    NULL,
  298.    1,0,
  299.    0,0,
  300.    GADGHCOMP | GRELBOTTOM | GRELWIDTH,
  301.    GADGIMMEDIATE | RELVERIFY | FOLLOWMOUSE,
  302.    PROPGADGET | GZZGADGET,
  303.    (APTR)&HorizImage,
  304.    NULL,
  305.    NULL,
  306.    0,
  307.    (APTR)&HorizPropInfo,
  308.    HORIZ,
  309.    NULL
  310. };
  311.  
  312. struct Image VertImage;
  313. struct PropInfo VertPropInfo = {
  314.    AUTOKNOB | FREEVERT,
  315.    0,0,
  316.    0,0,
  317.    0,0,
  318.    0,0,
  319.    0,0
  320. };
  321. struct Gadget VertGadget = {
  322.    NULL,
  323.    0,10,
  324.    0,0,
  325.    GADGHCOMP | GRELRIGHT | GRELHEIGHT,
  326.    GADGIMMEDIATE | RELVERIFY | FOLLOWMOUSE,
  327.    PROPGADGET | GZZGADGET,
  328.    (APTR)&VertImage,
  329.    NULL,
  330.    NULL,
  331.    0,
  332.    (APTR)&VertPropInfo,
  333.    VERT,
  334.    NULL
  335. };
  336.  
  337. struct IntuiText XRIntuiText = {
  338.    2,1,
  339.    JAM1,
  340.    0,0,
  341.    NULL,
  342.    CREDIT,
  343.    NULL
  344. };
  345. struct MenuItem XRMenuItem = {
  346.    NULL,
  347.    0,0,
  348.    0,0,
  349.    ITEMTEXT | ITEMENABLED,
  350.    0,
  351.    (APTR)&XRIntuiText,
  352.    0,
  353.    NULL,
  354.    NULL
  355. };
  356. struct Menu XRMenu = {
  357.    NULL,
  358.    0,0,
  359.    48,10,
  360.    MENUENABLED,
  361.    COPYRIGHT,
  362.    &XRMenuItem
  363. };
  364.  
  365. struct Window *Window = NULL;
  366. struct NewWindow XRWindow =
  367. {
  368.    0,0,
  369.    DEFWIDTH,DEFHEIGHT,
  370.    -1,-1,
  371.    CLOSEWINDOW | ACTIVEWINDOW | INACTIVEWINDOW | NEWSIZE |
  372.    GADGETUP | GADGETDOWN | MOUSEMOVE,
  373.    WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG | WINDOWSIZING | SIZEBRIGHT |
  374.    SIZEBBOTTOM | GIMMEZEROZERO | NOCAREREFRESH,
  375.    NULL,
  376.    NULL,
  377.    NULL,
  378.    NULL,
  379.    NULL,
  380.    MINWIDTH,MINHEIGHT,
  381.    0,0,
  382.    CUSTOMSCREEN
  383. };
  384.  
  385.  
  386. void main(argc, argv)
  387. int argc;
  388. char **argv;
  389. {
  390.    register struct Screen *scr;
  391.    register BOOL           bgone;
  392.    struct IntuiMessage    *message;
  393.    ULONG                   tick, class;
  394.    USHORT                  qualifier, last_id;
  395.    APTR                    iaddress;
  396.    BOOL                    update = FALSE;
  397.  
  398.    Timer=OFF;tick=DEFTICK;
  399.    if (argc==2) tick=atol(argv[1]);
  400.    if (tick==0) tick=1;
  401.    Secs=tick/1000000L;Micros=tick-(Secs*1000000L);
  402.  
  403.    InitProgram();
  404.  
  405.    FOREVER {
  406.       while (GetMsg(TimerPort)) {
  407.          if (BScreen!=FScreen) {
  408.             BltBitMapRastPort(BBMAP,Dx,Dy,WRPORT,0,0,WWidth,WHeight,0xC0);
  409.             QueueTimer(TimeRequest,Micros,Secs);
  410.          } else
  411.             Timer=OFF;
  412.       }
  413.  
  414.       Wait (1<<Window->UserPort->mp_SigBit | 1<<TimerPort->mp_SigBit);
  415.  
  416.       while ((message=(struct IntuiMessage *)GetMsg(Window->UserPort))) {
  417.          class=message->Class;
  418.          qualifier=message->Qualifier;
  419.          iaddress=message->IAddress;
  420.          ReplyMsg((struct Message *)message);
  421.  
  422.          bgone=TRUE;
  423.          for (
  424.             scr=IntuitionBase->FirstScreen;
  425.             scr!=NULL;
  426.             scr=scr->NextScreen
  427.          ) if (scr==BScreen) bgone=FALSE;
  428.          if (bgone) {BScreen=IntuitionBase->FirstScreen;SetScreen();}
  429.  
  430.          switch (class) {
  431.             case GADGETUP:
  432.                DoGadget(((struct Gadget *)iaddress)->GadgetID,qualifier);
  433.             break;
  434.  
  435.             case GADGETDOWN:
  436.                last_id=((struct Gadget *)iaddress)->GadgetID;
  437.             break;
  438.  
  439.             case MOUSEMOVE:
  440.                update=TRUE;
  441.             break;
  442.  
  443.             case ACTIVEWINDOW:
  444.                SwapIn();
  445.                SetWindowTitles(Window,-1,TITLE);
  446.                RefreshGadgets(Window->FirstGadget,Window,NULL);
  447.             break;
  448.  
  449.             case INACTIVEWINDOW:
  450.                SwapOut();
  451.                RefreshGadgets(Window->FirstGadget,Window,NULL);
  452.             break;
  453.  
  454.             case NEWSIZE:
  455.                AdjustProps();
  456.             break;
  457.  
  458.             case CLOSEWINDOW:
  459.                SwapOut();
  460.                Quit();
  461.             break;
  462.  
  463.             default:
  464.             break;
  465.          }
  466.       }
  467.       if (update) {
  468.          update=FALSE;
  469.          DoGadget(last_id,qualifier);
  470.       }
  471.    }
  472. }
  473.  
  474.  
  475. void InitProgram()
  476. {
  477.    BYTE i;
  478.  
  479.    if ((IntuitionBase=(struct IntuitionBase *)
  480.       OpenLibrary("intuition.library",0))==NULL)
  481.          Quit();
  482.  
  483.    if ((LayersBase=(struct LayersBase *)
  484.       OpenLibrary("layers.library",0))==NULL)
  485.          Quit();
  486.  
  487.    if ((GfxBase=(struct GfxBase *)
  488.       OpenLibrary("graphics.library",0))==NULL)
  489.          Quit();
  490.  
  491.    if ((TimeRequest=OpenTimer())==NULL)
  492.       Quit();
  493.  
  494.    FScreen=IntuitionBase->ActiveScreen;BScreen=FScreen;
  495.  
  496.    NumReg=1<<((FScreen->ViewPort).RasInfo->BitMap->Depth);
  497.    for (i=0;i<NumReg;i++) Colors[i]=GetRGB4(FScreen->ViewPort.ColorMap,i);
  498.  
  499.    OpenXRWindow();
  500.    SetWindowTitles(Window,TITLE,-1);
  501.    RefreshGadgets(Window->FirstGadget,Window,NULL);
  502.  
  503.    QueueTimer(TimeRequest,Micros,Secs);
  504. }
  505.  
  506.  
  507. void OpenXRWindow()
  508. {
  509.    struct Gadget *gadg;
  510.  
  511.    if ((XRWindow.Width=DEFWIDTH)>FScreen->Width)
  512.       if (FScreen->Width>=MINWIDTH)
  513.          XRWindow.Width=FScreen->Width;
  514.    if ((XRWindow.Height=DEFHEIGHT)>FScreen->Height)
  515.       if (FScreen->Height>=MINHEIGHT)
  516.          XRWindow.Height=FScreen->Height;
  517.  
  518.    XRWindow.Screen=FScreen;
  519.  
  520.    if ((Window=(struct Window *)OpenWindow(&XRWindow))==NULL)
  521.       Quit();
  522.  
  523.    SetMenuStrip(Window,&XRMenu);
  524.  
  525.    HorizPropInfo.HorizPot=VertPropInfo.VertPot=0;
  526.    for (gadg=Window->FirstGadget;gadg!=NULL;gadg=gadg->NextGadget) {
  527.       switch (gadg->GadgetType) {
  528.          case (SYSGADGET | GZZGADGET | WDOWNBACK):
  529.             PrevGadget.LeftEdge=gadg->LeftEdge-24;
  530.             AddGadget(Window,&PrevGadget,0);
  531.             NextGadget.LeftEdge=PrevGadget.LeftEdge-24;
  532.             AddGadget(Window,&NextGadget,0);
  533.             EnterGadget.LeftEdge=NextGadget.LeftEdge-24;
  534.             AddGadget(Window,&EnterGadget,0);
  535.          break;
  536.  
  537.          case (SYSGADGET | GZZGADGET | SIZING):
  538.             HorizGadget.TopEdge=gadg->TopEdge;
  539.             HorizGadget.Width=-gadg->Width;
  540.             HorizGadget.Height=gadg->Height;
  541.             AddGadget(Window,&HorizGadget,-1);
  542.             VertGadget.LeftEdge=gadg->LeftEdge;
  543.             VertGadget.Width=gadg->Width;
  544.             VertGadget.Height=-gadg->Height-10;
  545.             AddGadget(Window,&VertGadget,-1);
  546.          break;
  547.       }
  548.    }
  549.  
  550.    if (!AdjustLimits()) Quit();
  551.    AdjustProps();
  552.    RefreshGadgets(Window->FirstGadget,Window,NULL);  
  553.    SetAPen(WRPORT,0);SetOPen(WRPORT,0);
  554. }
  555.  
  556.  
  557.  
  558. void AdjustProps()
  559. {
  560.    WWidth=Window->Width-Window->BorderLeft-Window->BorderRight;
  561.    ModifyProp(
  562.       &HorizGadget,Window,NULL,
  563.       AUTOKNOB | FREEHORIZ,
  564.       HorizPropInfo.HorizPot,0,
  565.       (WWidth*0xFFFF)/BWidth,0
  566.    );
  567.    WHeight=Window->Height-Window->BorderTop-Window->BorderBottom;
  568.    ModifyProp(
  569.       &VertGadget,Window,NULL,
  570.       AUTOKNOB | FREEVERT,
  571.       0,VertPropInfo.VertPot,
  572.       0,(WHeight*0xFFFF)/BHeight
  573.    );
  574.    Dy=((ULONG)(BHeight-WHeight)*VertPropInfo.VertPot+(1L<<15))>>16;
  575.    Dx=((ULONG)(BWidth-WWidth)*HorizPropInfo.HorizPot+(1L<<15))>>16;
  576. }
  577.  
  578.  
  579. BOOL AdjustLimits()
  580. {
  581.    SHORT maxwidth, maxheight;
  582.  
  583.    FWidth=FScreen->Width;FHeight=FScreen->Height;
  584.    BWidth=BScreen->Width;BHeight=BScreen->Height;
  585.  
  586.    if ((maxwidth=BWidth+Window->BorderLeft+Window->BorderRight)>FWidth)
  587.       maxwidth=FWidth;
  588.    if ((maxheight=BHeight+Window->BorderTop+Window->BorderBottom)>FHeight)
  589.       maxheight=FHeight;
  590.    if (maxwidth<Window->Width) {
  591.       SizeWindow(Window,maxwidth-Window->Width,0);
  592.       while (Window->Width!=maxwidth);
  593.    }
  594.    if (maxheight<Window->Height) {
  595.       SizeWindow(Window,0,maxheight-Window->Height);
  596.       while (Window->Height!=maxheight);
  597.    }
  598.    return((BOOL)WindowLimits(Window,0,0,maxwidth,maxheight));
  599. }
  600.  
  601.  
  602. void DoGadget(id,shift)
  603. USHORT id, shift;
  604. {
  605.    switch (id) {
  606.       case VERT:
  607.          Dy=((ULONG)(BHeight-WHeight)*VertPropInfo.VertPot+(1L<<15))>>16;
  608.       break;
  609.  
  610.       case HORIZ:
  611.          Dx=((ULONG)(BWidth-WWidth)*HorizPropInfo.HorizPot+(1L<<15))>>16;
  612.       break;
  613.  
  614.       case NEXT:
  615.          IncScreen();
  616.       break;
  617.  
  618.       case PREV:
  619.          DecScreen();
  620.       break;
  621.  
  622.       case ENTER:
  623.          if (BScreen!=FScreen) {
  624.             ScreenToFront(BScreen);
  625.             if (
  626.                ((shift & LSHFTCLCK)==LSHFTCLCK) ||
  627.                ((shift & RSHFTCLCK)==RSHFTCLCK)
  628.             ) Follow();
  629.          }
  630.       break;
  631.  
  632.       default:
  633.       break;
  634.    }   
  635.    if (BScreen!=FScreen)
  636.       BltBitMapRastPort(BBMAP,Dx,Dy,WRPORT,0,0,WWidth,WHeight,0xC0);
  637. }
  638.  
  639.  
  640. void IncScreen()
  641. {
  642.    struct Screen *VScreen;
  643.  
  644.    VScreen=BScreen;
  645.    if ((BScreen=BScreen->NextScreen)==NULL)
  646.       BScreen=IntuitionBase->FirstScreen;
  647.    if (VScreen!=BScreen) SetScreen();
  648. }
  649.  
  650.  
  651. void DecScreen()
  652. {
  653.    struct Screen *PrevScreen, *VScreen;
  654.  
  655.    VScreen=BScreen;
  656.    for (
  657.       PrevScreen=IntuitionBase->FirstScreen;
  658.       (PrevScreen->NextScreen!=BScreen) && (PrevScreen->NextScreen!=NULL);
  659.       PrevScreen=PrevScreen->NextScreen
  660.    );
  661.    BScreen=PrevScreen;
  662.    if (VScreen!=BScreen) SetScreen();
  663. }
  664.  
  665.  
  666. void SetScreen()
  667. {
  668.    RectFill(WRPORT,0,0,WWidth,WHeight);
  669.  
  670.    if (BScreen==FScreen) SwapOut();
  671.    else {
  672.       SwapIn();
  673.       if (Timer==OFF) {
  674.          Timer=ON;
  675.          if (CheckIO(TimeRequest)) QueueTimer(TimeRequest,Micros,Secs);
  676.       }
  677.    }
  678.  
  679.    if (!AdjustLimits()) Quit();
  680.    AdjustProps();
  681.    SetWindowTitles(Window,BScreen->Title,-1);
  682.    RefreshGadgets(Window->FirstGadget,Window,NULL);
  683. }
  684.  
  685.  
  686. struct TIMREQ *OpenTimer()
  687. {
  688.    struct TIMREQ *tr;
  689.  
  690.    if (
  691.       ((TimerPort=(struct MsgPort *)CreatePort(0,0))==NULL) ||
  692.       ((tr=(struct TIMREQ *)
  693.          CreateExtIO(TimerPort,sizeof(struct TIMREQ)))==NULL) ||
  694.       (OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)tr,0))
  695.    )
  696.       return(NULL);
  697.    else
  698.       return(tr);
  699. }
  700.  
  701.  
  702. void CloseTimer(tr)
  703. struct TIMREQ *tr;
  704. {
  705.    while (CheckIO(tr)==NULL) {
  706.       Wait (1<<TimerPort->mp_SigBit);
  707.       (void)GetMsg(TimerPort);
  708.    }
  709.    if (tr->tr_node.io_Device) CloseDevice((struct IORequest *)tr);
  710.    if (TimerPort!=NULL) DeletePort(TimerPort);
  711.    DeleteExtIO(tr,sizeof(struct TIMREQ));
  712. }
  713.  
  714.  
  715. void QueueTimer(tr,micros,secs)
  716. struct TIMREQ *tr;
  717. ULONG         micros;
  718. ULONG         secs;
  719. {
  720.    struct timeval delay;
  721.  
  722.    delay.tv_secs=secs;
  723.    delay.tv_micro=micros;
  724.    tr->tr_time=delay;
  725.    tr->tr_node.io_Command=TR_ADDREQUEST;
  726.    SendIO((struct IORequest *)tr);
  727. }
  728.  
  729.  
  730. void Follow()
  731. {
  732.    BYTE   i;
  733.    struct Screen *scr;
  734.  
  735.    SwapOut();
  736.    scr=FScreen;FScreen=BScreen;BScreen=scr;
  737.    NumReg=1<<((FScreen->ViewPort).RasInfo->BitMap->Depth);
  738.    for (i=0;i<NumReg;i++) Colors[i]=GetRGB4(FScreen->ViewPort.ColorMap,i);
  739.  
  740.    ClearMenuStrip(Window);
  741.    CloseWindow(Window);
  742.    OpenXRWindow();
  743.  
  744.    SetWindowTitles(Window,BScreen->Title,-1);
  745.    RefreshGadgets(Window->FirstGadget,Window,NULL);
  746. }
  747.  
  748.  
  749. void SwapIn()
  750. {
  751.    LoadRGB4(FVPORT,(BScreen->ViewPort.ColorMap->ColorTable),NumReg);
  752. }
  753.  
  754.  
  755. void SwapOut()
  756. {
  757.    LoadRGB4(FVPORT,(ULONG)Colors,NumReg);
  758. }
  759.  
  760.  
  761. void Quit()
  762. {
  763.    if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  764.    if (LayersBase) CloseLibrary(LayersBase);
  765.    if (GfxBase) CloseLibrary(GfxBase);
  766.    if (Window) {ClearMenuStrip(Window);CloseWindow(Window);}
  767.    if (TimeRequest) CloseTimer(TimeRequest);
  768.  
  769.    exit(0L);
  770. }
  771.  
  772.